﻿Imports System.Collections.ObjectModel
Imports System.ComponentModel

#Region " LocalGroupクラス "
''' <summary>
''' ローカルのグループを表すクラスです。
''' </summary>
''' <remarks></remarks>
Public NotInheritable Class LocalGroup
  Inherits DirectoryObject
  Implements IGroup

#Region " フレンドコンストラクター "
  ''' <summary>
  ''' <see cref="DirectoryEntry"/> を指定して <see cref="LocalGroup"/> クラスの新しいインスタンスを初期化します。
  ''' </summary>
  ''' <param name="entry"><see cref="DirectoryEntry"/>。</param>
  ''' <remarks></remarks>
  Friend Sub New(entry As DirectoryEntry)
    MyBase.New(entry)
  End Sub
#End Region

#Region " パブリックプロパティ "
  ''' <summary><see cref="Entry"/> の ADSI Group オブジェクトを取得します。</summary>
  ''' <value></value>
  ''' <returns><see cref="Entry"/> の ADSI Group オブジェクト。</returns>
  ''' <remarks></remarks>
  Public ReadOnly Property Native As IADsGroup Implements IGroup.Native
    Get
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      Return DirectCast(MyBase.Entry.NativeObject, IADsGroup)
    End Get
  End Property
#End Region
End Class
#End Region

#Region " DomainGroupクラス "
''' <summary>
''' ドメインのグループを表すクラスです。
''' </summary>
''' <remarks></remarks>
<DataObject()>
Public NotInheritable Class DomainGroup
  Inherits DomainObject
  Implements IGroup

#Region " プライベートフィールド "
  Private ReadOnly _token As Integer
  Private ReadOnly _security As Boolean
  Private ReadOnly _scope, _type As String
  Private ReadOnly _scopeType As DomainGroupScopeType
#End Region

#Region " フレンドコンストラクター "
  ''' <summary>
  ''' <see cref="DirectoryEntry"/> を指定して <see cref="DomainGroup"/> クラスの新しいインスタンスを初期化します。
  ''' </summary>
  ''' <param name="entry"><see cref="DirectoryEntry"/>。</param>
  ''' <remarks></remarks>
  Friend Sub New(entry As DirectoryEntry)
    MyBase.New(entry)

    entry.Invoke("GetInfoEx", New Object() {"primaryGroupToken"}, 0)
    _token = Convert.ToInt32(entry.Properties.Item("primaryGroupToken").Value)

    Dim gtype = Convert.ToInt32(entry.Properties.Item("groupType").Value)
    If gtype < 0 Then
      _security = True
      _type = "セキュリティ"
    Else
      gtype += Int32.MinValue
      _type = "配布"
    End If
    _scopeType = DirectCast([Enum].ToObject(GetType(DomainGroupScopeType), gtype), DomainGroupScopeType)
    _scope = GetGroupScope()  'グループのスコープを取得
  End Sub
#End Region

#Region " パブリックプロパティ "
  ''' <summary>
  ''' <see cref="Entry"/> の ADSI Group オブジェクトを取得します。
  ''' </summary>
  ''' <value></value>
  ''' <returns><see cref="Entry"/> の ADSI Group オブジェクト。</returns>
  ''' <remarks></remarks>
  Public ReadOnly Property Native As IADsGroup Implements IGroup.Native
    Get
      If MyBase.IsDisposed Then
        Throw New ObjectDisposedException(Me.GetType().Name)
      End If
      Return DirectCast(MyBase.Entry.NativeObject, IADsGroup)
    End Get
  End Property

  ''' <summary>
  ''' グループのスコープを取得します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>グループのスコープ。</returns>
  ''' <remarks></remarks>
  Public ReadOnly Property Scope As String
    Get
      Return _scope
    End Get
  End Property

  ''' <summary>
  ''' グループのスコープタイプを取得します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>グループのスコープタイプ。</returns>
  ''' <remarks></remarks>
  Public ReadOnly Property ScopeType As DomainGroupScopeType
    Get
      Return _scopeType
    End Get
  End Property

  ''' <summary>
  ''' セキュリティ グループかどうかを取得します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>セキュリティ グループかどうかを示す値。</returns>
  ''' <remarks></remarks>
  Public ReadOnly Property SecurityEnabled As Boolean
    Get
      Return _security
    End Get
  End Property

  ''' <summary>
  ''' プライマリ グループ トークンを取得します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>プライマリ グループ トークン。</returns>
  ''' <remarks></remarks>
  Public ReadOnly Property Token As Integer
    Get
      Return _token
    End Get
  End Property

  ''' <summary>
  ''' グループの種類を取得します。
  ''' </summary>
  ''' <value></value>
  ''' <returns>グループの種類。</returns>
  ''' <remarks></remarks>
  Public ReadOnly Property [Type] As String
    Get
      Return _type
    End Get
  End Property
#End Region

#Region " パブリックメソッド "
  ''' <summary>
  ''' 指定した名前のグループを検索します。このメソッドはデータバインド用です。
  ''' </summary>
  ''' <param name="name">名前。</param>
  ''' <returns>グループ。</returns>
  ''' <remarks></remarks>
  <DataObjectMethod(DataObjectMethodType.Select)>
  Public Shared Function FindByName(name As String) As DomainGroup
    Return DirectCast(DirectoryAccess.FindDirectoryObject(name, CategoryType.Group), DomainGroup)
  End Function

  ''' <summary>
  ''' グループの一覧を取得します。このメソッドはデータバインド用です。
  ''' </summary>
  ''' <returns>グループの一覧。</returns>
  ''' <remarks></remarks>
  <DataObjectMethod(DataObjectMethodType.Select)>
  Public Shared Function GetGroups() As IList(Of DomainGroup)
    Return DirectoryAccess.GetGroups(Of DomainGroup)()  'グループを取得
  End Function
#End Region

#Region " プライベートメソッド "
  ''' <summary>
  ''' グループのスコープを取得します。
  ''' </summary>
  ''' <returns>グループのスコープ。</returns>
  ''' <remarks></remarks>
  Private Function GetGroupScope() As String
    Select Case Me.ScopeType
      Case DomainGroupScopeType.BuiltInLocal
        Return "ビルトイン ローカル"
      Case DomainGroupScopeType.DomainLocal
        Return "ドメイン ローカル"
      Case DomainGroupScopeType.[Global]
        Return "グローバル"
      Case Else
        Return "ユニバーサル"
    End Select
  End Function
#End Region
End Class
#End Region